package com.huaxin.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.device.constant.AlarmMessageParams;
import com.huaxin.device.dto.ResponseCode;
import com.huaxin.device.dto.ResponseResult;
import com.huaxin.device.dto.request.AlarmThresholdTemplateCreateReqDTO;
import com.huaxin.device.dto.request.AlarmThresholdTemplatePageListReqDTO;
import com.huaxin.device.dto.request.AlarmThresholdTemplateUpdateReqDTO;
import com.huaxin.device.event.AlarmTemplateUpdatedEvent;
import com.huaxin.device.mapper.AlarmThresholdTemplateMapper;
import com.huaxin.device.mapping.AlarmThresholdTemplateMapping;
import com.huaxin.device.models.AlarmMessageParam;
import com.huaxin.device.models.AlarmThresholdTemplate;
import com.huaxin.device.service.AlarmThresholdTemplateService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.springframework.util.StringUtils.hasText;

@Service
@RequiredArgsConstructor
public class AlarmThresholdTemplateServiceImpl
        extends ServiceImpl<AlarmThresholdTemplateMapper, AlarmThresholdTemplate>
        implements AlarmThresholdTemplateService {

    private final ApplicationContext applicationContext;
    private final ApplicationEventPublisher eventPublisher;
    private final AlarmThresholdTemplateMapping mapping;

    @Override
    public ResponseResult<AlarmThresholdTemplate> create(AlarmThresholdTemplateCreateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数不能为空");
        }
        if (!hasText(in.getTemplateName())) {
            return ResponseResult.parameterError(null, "模板名称不能为空");
        }
        if (!isValidTemplate(in.getMessageTemplate())) {
            return ResponseResult.parameterError(null, "消息模板参数错误");
        }
        AlarmThresholdTemplate entity = mapping.toEntity(in);
        if (!this.save(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "创建失败，请稍后再试", null);
        }
        AlarmThresholdTemplate created = this.getById(entity.getId());
        return ResponseResult.ok(created);
    }

    /**
     * 校验模板参数是否合法
     *
     * @param template 模板
     * @return 是否合法
     */
    private boolean isValidTemplate(String template) {
        Set<String> allowedKeys = AlarmMessageParams.PARAMS.stream()
                .map(AlarmMessageParam::getParam)
                .collect(Collectors.toSet());

        Pattern pattern = Pattern.compile("\\{(\\w+)}");
        Matcher matcher = pattern.matcher(template);

        while (matcher.find()) {
            String key = matcher.group(1);
            if (!allowedKeys.contains(key)) {
                return false; // 包含非法参数
            }
        }
        return true;
    }

    @Override
    public AlarmThresholdTemplate getByTemplateId(String id) {
        return this.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> update(AlarmThresholdTemplateUpdateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数不能为空");
        }
        if (!hasText(in.getId())) {
            return ResponseResult.parameterError(null, "模板ID不能为空");
        }
        if (!hasText(in.getTemplateName())) {
            return ResponseResult.parameterError(null, "模板名称不能为空");
        }
        if (!isValidTemplate(in.getMessageTemplate())) {
            return ResponseResult.parameterError(null, "消息模板参数错误");
        }
        AlarmThresholdTemplate entity = this.getByTemplateId(in.getId());
        if (entity == null) {
            return ResponseResult.failure(ResponseCode.NOT_FOUND, "未找到指定的报警阈值模板", null);
        }
        mapping.updateEntity(in, entity);
        if (!this.updateById(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "更新失败，请稍后再试", null);
        }

        eventPublisher.publishEvent(new AlarmTemplateUpdatedEvent(entity.getId()));

        return ResponseResult.ok("更新成功");
    }

    @Override
    public ResponseResult<String> delete(String id) {
        if (!hasText(id)) {
            return ResponseResult.parameterError(null, "模板ID不能为空");
        }
        AlarmThresholdTemplate entity = this.getByTemplateId(id);
        if (entity == null) {
            return ResponseResult.failure(ResponseCode.NOT_FOUND, "未找到指定的报警阈值模板", null);
        }

        // 系统默认模板不允许删除
        if (Boolean.TRUE.equals(entity.getIsDefault())) {
            return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "系统默认模板不允许删除", null);
        }

        boolean removed = this.applicationContext.getBean(AlarmThresholdTemplateService.class).removeById(id);
        if (!removed) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
        }
        return ResponseResult.ok("删除成功");
    }

    @Override
    public ResponseResult<IPage<AlarmThresholdTemplate>> pageQuery(AlarmThresholdTemplatePageListReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "分页查询参数不能为空");
        }

        IPage<AlarmThresholdTemplate> page = new Page<>(in.getPageNum(), in.getPageSize());
        LambdaQueryWrapper<AlarmThresholdTemplate> wrapper = new LambdaQueryWrapper<>();

        // 按设备类型过滤
        if (hasText(in.getDeviceType())) {
            wrapper.eq(AlarmThresholdTemplate::getDeviceType, in.getDeviceType());
        }

        // 按优先级过滤
        if (in.getAlarmLevel() != null) {
            wrapper.eq(AlarmThresholdTemplate::getAlarmLevel, in.getAlarmLevel());
        }

        // 关键字搜索：模板名称或描述
        if (hasText(in.getKeyword())) {
            wrapper.and(w -> w.like(AlarmThresholdTemplate::getTemplateName, in.getKeyword())
                    .or()
                    .like(AlarmThresholdTemplate::getDescription, in.getKeyword()));
        }

        // 按组织家族ID过滤（可选）
        if (hasText(in.getFamilyId())) {
            wrapper.eq(AlarmThresholdTemplate::getFamilyId, in.getFamilyId());
        }

        // 按创建时间排序
        wrapper.orderByDesc(AlarmThresholdTemplate::getCreatedAt);

        IPage<AlarmThresholdTemplate> resultPage = this.page(page, wrapper);
        return ResponseResult.ok(resultPage);
    }
}